import os
import shutil
import tkinter as tk
from tkinter import filedialog, messagebox
import json


class FileSyncApp:
    def __init__(self, master):
        self.master = master
        self.master.title("文件同步工具")

        self.task_file = "tasks.json"
        self.tasks = self.load_tasks()

        # 界面组件
        self.source_label = tk.Label(master, text="选择源文件夹:")
        self.source_label.pack()
        self.source_button = tk.Button(master, text="选择文件夹", command=self.select_source)
        self.source_button.pack()

        self.target_label = tk.Label(master, text="选择目标文件夹:")
        self.target_label.pack()
        self.target_button = tk.Button(master, text="选择文件夹", command=self.select_target)
        self.target_button.pack()

        self.save_task_button = tk.Button(master, text="保存任务", command=self.save_task)
        self.save_task_button.pack()

        self.execute_button = tk.Button(master, text="执行同步", command=self.execute_sync)
        self.execute_button.pack()

        self.task_listbox = tk.Listbox(master)
        self.task_listbox.pack()
        self.task_listbox.bind('<<ListboxSelect>>', self.load_selected_task)

        self.load_tasks_into_listbox()

    def load_tasks(self):
        if os.path.exists(self.task_file):
            with open(self.task_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        return []

    def save_tasks(self):
        with open(self.task_file, 'w', encoding='utf-8') as f:
            json.dump(self.tasks, f)

    def select_source(self):
        self.source_folder = filedialog.askdirectory()
        self.source_label.config(text=f"源文件夹: {self.source_folder}")

    def select_target(self):
        self.target_folder = filedialog.askdirectory()
        self.target_label.config(text=f"目标文件夹: {self.target_folder}")

    def save_task(self):
        task_name = f"Task {len(self.tasks) + 1}"
        self.tasks.append({
            "name": task_name,
            "source": self.source_folder,
            "target": self.target_folder
        })
        self.save_tasks()
        self.load_tasks_into_listbox()
        messagebox.showinfo("任务保存", f"任务 '{task_name}' 已保存")

    def load_tasks_into_listbox(self):
        self.task_listbox.delete(0, tk.END)
        for task in self.tasks:
            self.task_listbox.insert(tk.END, task["name"])

    def load_selected_task(self, event):
        selected_index = self.task_listbox.curselection()
        if selected_index:
            selected_task = self.tasks[selected_index[0]]
            self.source_folder = selected_task['source']
            self.target_folder = selected_task['target']
            self.source_label.config(text=f"源文件夹: {self.source_folder}")
            self.target_label.config(text=f"目标文件夹: {self.target_folder}")

    def execute_sync(self):
        if not hasattr(self, 'source_folder') or not hasattr(self, 'target_folder'):
            messagebox.showerror("错误", "请先选择源文件夹和目标文件夹")
            return

        for root, dirs, files in os.walk(self.source_folder):
            for file in files:
                src_file_path = os.path.join(root, file)
                rel_path = os.path.relpath(src_file_path, self.source_folder)
                target_file_path = os.path.join(self.target_folder, rel_path)

                # 创建目标文件夹
                os.makedirs(os.path.dirname(target_file_path), exist_ok=True)

                # 同步文件
                if not os.path.exists(target_file_path) or \
                        os.path.getmtime(src_file_path) > os.path.getmtime(target_file_path):
                    shutil.copy2(src_file_path, target_file_path)
                    print(f"同步: {src_file_path} 到 {target_file_path}")

        # 删除目标中不存在的文件
        for root, dirs, files in os.walk(self.target_folder):
            for file in files:
                target_file_path = os.path.join(root, file)
                rel_path = os.path.relpath(target_file_path, self.target_folder)
                src_file_path = os.path.join(self.source_folder, rel_path)
                if not os.path.exists(src_file_path):
                    os.remove(target_file_path)
                    print(f"删除: {target_file_path}")

        messagebox.showinfo("同步完成", "文件同步已完成")


if __name__ == "__main__":
    root = tk.Tk()
    app = FileSyncApp(root)
    root.mainloop()
